package com.pjc.utils;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * mysql帮助类
 * 
 * @author 王畅
 * @since 2015年6月21日
 */
public class MysqlUtils {
	static Logger log = LoggerFactory.getLogger(MysqlUtils.class);

	/**
	 * 查询单对象
	 * 
	 * @param conn
	 * @param handler
	 * @param sql
	 * @param params
	 * @return
	 * @throws SQLException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public static <T> T queryObj(Connection conn, RowHandler<T> handler, String sql, Object[] params) throws SQLException, InstantiationException, IllegalAccessException {
		PreparedStatement preStat = null;
		ResultSet rs = null;
		try {
			preStat = conn.prepareStatement(sql);
			if (params != null) {
				setPreStateParams(preStat, params);
			}
			rs = preStat.executeQuery();
			T clazz = null;
			if (rs.next()) {
				clazz = handler.execute(rs);
			}
			return clazz;
		} finally {
			if (rs != null)
				rs.close();
			if (preStat != null)
				preStat.close();
			if (conn != null)
				conn.close();
		}
	}

	/**
	 * 查询列表
	 * 
	 * @param conn
	 * @param handler
	 * @param sql
	 * @param params
	 * @return
	 * @throws SQLException
	 */
	public static <T> List<T> queryList(Connection conn, RowHandler<T> handler, String sql, Object[] params) throws SQLException {
		PreparedStatement preStat = null;
		ResultSet rs = null;
		try {
			preStat = conn.prepareStatement(sql);
			if (params != null) {
				setPreStateParams(preStat, params);
			}
			rs = preStat.executeQuery();
			List<T> list = new ArrayList<T>();
			while (rs.next()) {
				list.add(handler.execute(rs));
			}
			return list;
		} finally {
			if (rs != null)
				rs.close();
			if (preStat != null)
				preStat.close();
			if (conn != null)
				conn.close();
		}
	}

	public static void setPreStateParams(PreparedStatement preStat, Object[] params) throws SQLException {
		int i = 1;
		for (Object p : params) {
			if (p instanceof Integer) {
				preStat.setInt(i, ((Integer) p).intValue());
			}
			if (p instanceof Short) {
				preStat.setShort(i, ((Short) p).shortValue());
			}
			if (p instanceof Byte) {
				preStat.setByte(i, ((Byte) p).byteValue());
			}
			if (p instanceof Long) {
				preStat.setLong(i, ((Long) p).longValue());
			}
			if (p instanceof String) {
				preStat.setString(i, (String) p);
			}
			if (p instanceof Float) {
				preStat.setFloat(i, ((Float) p).floatValue());
			}
			if (p instanceof Double) {
				preStat.setDouble(i, ((Double) p).doubleValue());
			}
			if (p instanceof Timestamp) {
				preStat.setTimestamp(i, (Timestamp) p);
			}
			if (p instanceof Date) {
				preStat.setDate(i, (Date) p);
			}
			if (p instanceof byte[]) {
				preStat.setBytes(i, (byte[]) p);
			}
			++i;
		}
	}

	public static abstract interface Handler<T> {
		public abstract T execute(ResultSet paramResultSet) throws SQLException;
	}

	public static abstract interface RowHandler<T> {
		public abstract T execute(ResultSet paramResultSet) throws SQLException;
	}
}